package com.zte.claa.inficombo.csa.app.controller;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.zte.claa.inficombo.csa.app.controller.ret.ApiResult;
import com.zte.claa.inficombo.csa.app.model.dev.DevBase;
import com.zte.claa.inficombo.csa.app.model.dev.DevTypeModel;
import com.zte.claa.inficombo.csa.app.model.redis.DevMeteData;
import com.zte.claa.inficombo.csa.app.service.rptparse.ParserContainer;
import com.zte.claa.inficombo.csa.app.util.JsonUtils;

import io.swagger.annotations.ApiOperation;

/**
 * @author 0283000121
 * 
 * 品茗数据上报接口
 *
 */
@RestController
@RequestMapping("/rptdata/v2/pm")
public class PinMingApiController extends BaseController {
	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	// logger
	private Logger logger = LoggerFactory.getLogger(PinMingApiController.class);
	
	@Autowired 
	private ParserContainer	container;
	
	protected Timestamp parseCreatetime(String dt){
		try{
			SimpleDateFormat sdf = new SimpleDateFormat(DATETIME_FORMAT);
			return new Timestamp(sdf.parse(dt).getTime());	
		}catch(Exception ex){
			return new Timestamp(System.currentTimeMillis());
		}
	}
			
	
	protected int getIntParamDef(HttpServletRequest request, String name, int def) {
		try {
			return Integer.parseInt(request.getParameter(name));
		}
		catch (Exception e) {
//			logger.warn("Parse int fail! name: " + name + " ,returning default value: " + def);
			return def;
		}		
	}
	
	protected String getStrParamDef(HttpServletRequest request, String name, String def) {
		try {
			return (request.getParameter(name) == null) ? def : request.getParameter(name);
		}catch (Exception e) {
			// TODO: handle exception
			return def;
		}
	}
	
	protected double getDoubleParamDef(HttpServletRequest request, String name, double def) {
		try {
			return Double.parseDouble(request.getParameter(name));
		}
		catch (Exception e) {
			return def;
		}		
	}
	
	
	
	/**
	 * 获取设备基础数据
	 * @param deveui	传入deveui
	 * @return DevBase
	 */
	protected DevBase getDevBase(String deveui) {
		if(deveui == null || "".equals(deveui)){
			logger.error("[*!!*]invalid deveui!");
			return null;
		}
		//
		DevBase dev = this.container.getCacheManager().getDev(deveui);
		if(dev == null){
			logger.error("[*@@*]Can not get dev data: " + deveui);
			return null;
		}
		DevTypeModel dtm = this.container.getCacheManager().getDevTypeModel(dev.getDevType());
		if(dtm == null || dtm.getDmList() == null){
			logger.error("[*!!*]Can not get datamodel for devtype="+dev.getDevType());
			return null;
		}
		
		return dev;
	}
	

    /**
     * 品茗塔吊信息推送
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * 
     * 采集塔吊信息 
     *  deveui 		varchar 50 	必选		设备编号
		create_time varchar 100	必选 	yyyy-MM-dd HH:mm:ss 格式
		angle 		float 	4 	必选 	塔吊朝向角度，单位：°
		weight 		float 	4 	必选 	塔吊吊重，单位：kg
		height 		float 	4 	必选 	塔吊高度，单位：m
		range 		float 	4 	必选 	塔吊变幅，单位：°/min
		speed 		float 	4 	必选 	当前风速，单位：m/s

     */
	@ApiOperation(value = "设备数据推送", notes = "品茗塔吊信息推送")
	@RequestMapping(value={"/towerstatus"})
	@ResponseBody
	public ApiResult<?> devDataRpt(HttpServletRequest request) throws Exception{
		ApiResult<String> ret = new ApiResult<String>();
				
		String deveui = this.getStrParamDef(request, "deveui", "");
		String createtime = this.getStrParamDef(request, "create_time", "");
		double angle = this.getDoubleParamDef(request, "angle",  0);
		double weight = this.getDoubleParamDef(request, "weight", 0);
		double height = this.getDoubleParamDef(request, "height", 0);
		double range = this.getDoubleParamDef(request, "range", 0);
		double speed = this.getDoubleParamDef(request, "speed", 0);
		
		logger.info("devDataRpt: deveui=" + deveui + ", create_time=" + createtime + 
				", angle=" + angle + ", weight=" + weight + ", height=" + height + 
				", range=" + range + ", speed=" + speed);
		
		// 获取DevBase信息
		DevBase dev = this.getDevBase(deveui);
		if (dev == null) {
			ret.setRemark("couldn't get devbase info");
			ret.setResult(ApiResult.RET_FAIL);
			return ret;
		}
		
		// 转换为Metadata
		// Map<String, Object> mdata = JsonUtils.beanToHashMap(parseData);
		Map<String, Object> mdata = new HashMap<String, Object>();
//		mdata.put("deveui", deveui);
		mdata.put("angle",  angle);
		mdata.put("weight", weight);
		mdata.put("height", height);
		// range 为mysql 关键字，数据库表字段对应为scope
//		mdata.put("range",  range);
		mdata.put("scope",  range);
		mdata.put("speed",  speed);
		
		DevMeteData meteData = new DevMeteData();
		meteData.setAppeui(dev.getAppEui());
		meteData.setDeveui(dev.getDevEui());
		meteData.setDevname(dev.getDevName());
		meteData.setDevtype(dev.getDevType());
		meteData.setPort("0");
		meteData.setProjectid(dev.getProjectId());
		meteData.setRpttime(parseCreatetime(createtime));
		// 删除模型无关字段...
		
		meteData.setMdata(mdata);
		
		// 存库并通知
		// 持久化数据.
		DevTypeModel dtm = this.container.getCacheManager().getDevTypeModel(dev.getDevType());
		this.container.getPersisService().saveDevMeteData(meteData, dtm.getBase().getTbname());
		// 构造广播数据，进行redis发布...
		String pubMsg = JsonUtils.toJson(meteData);
		this.container.getUpdataPublisher().publishMessage(pubMsg);
		logger.info("[*^_^*]Publish metedata message ok: "+pubMsg);
		
		// 返回响应
		ret.setData("");
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
	 * 品茗升降机信息推送
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 * 
	 * 采集升降机信息
	    deveui varchar 50 必选 设备编号
		create_time varchar 100 必选 yyyy-MM-dd HH:mm:ss 格式
		status Byte 1 必选 升降机状态: 0:停止; 1:上; 2:下
	 */
	@ApiOperation(value = "设备数据推送", notes = "品茗升降机信息推送")
	@RequestMapping(value={"/liftstatus"})
	@ResponseBody
	public ApiResult<?> devAlarmRpt(HttpServletRequest request) throws Exception{
		ApiResult<String> ret = new ApiResult<String>();
		// PinMingLiftParseResult parseData = new PinMingLiftParseResult();
		
		String deveui = this.getStrParamDef(request, "deveui", "");
		String createtime = this.getStrParamDef(request, "create_time", "");
		int status = this.getIntParamDef(request, "status",  0);
		double weight = this.getDoubleParamDef(request, "weight", 0);
		
		logger.info("devDataRpt: deveui=" + deveui + ", create_time=" + createtime + ", status=" + status + ", weight=" + weight);
		
		// 获取DevBase信息
		DevBase dev = this.getDevBase(deveui);
		if (dev == null) {
			ret.setRemark("couldn't get devbase info");
			ret.setResult(ApiResult.RET_FAIL);
			return ret;
		}
		
		// 转换为Metadata
		// Map<String, Object> mdata = JsonUtils.beanToHashMap(parseData);
		Map<String, Object> mdata = new HashMap<String, Object>();
		
//		mdata.put("deveui", deveui);
		mdata.put("status", status);
		mdata.put("weight", weight);
		
		DevMeteData meteData = new DevMeteData();
		meteData.setAppeui(dev.getAppEui());
		meteData.setDeveui(dev.getDevEui());
		meteData.setDevname(dev.getDevName());
		meteData.setDevtype(dev.getDevType());
		meteData.setPort("0");
		meteData.setProjectid(dev.getProjectId());
		meteData.setRpttime(parseCreatetime(createtime));
		// 删除模型无关字段...
			
		meteData.setMdata(mdata);		
		
		// 存库并通知
		// 持久化数据.
		DevTypeModel dtm = this.container.getCacheManager().getDevTypeModel(dev.getDevType());
		this.container.getPersisService().saveDevMeteData(meteData, dtm.getBase().getTbname());
		// 构造广播数据，进行redis发布...
		String pubMsg = JsonUtils.toJson(meteData);
		this.container.getUpdataPublisher().publishMessage(pubMsg);
		logger.info("[*^_^*]Publish metedata message ok: "+pubMsg);
		
		
		ret.setData("");
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	
}
